#pragma once

#include <string>
#include <vector>
#include <unordered_map>

std::vector<std::string_view> toArgs( const std::string_view line ) {
    std::vector<std::string_view> args;
    size_t pos = 0;
    for ( size_t i = 0; i < line.size(); ++i )
    {
        if ( line[i] == ' ' )
        {
            args.push_back( line.substr( pos, i - pos ) );
            pos = i + 1;
        }
    }
    args.push_back( line.substr( pos ) );
    return args;
}

bool isRegisterName( std::string_view line ) {
    return line.find_first_not_of( "abcdefghijklmnopqrstuvwxyz" ) == std::string_view::npos;
}

std::unordered_map<std::string, int> assembler( const std::vector<std::string> & program ) {
    std::unordered_map<std::string, int> regs;
    for ( int i = 0; i < static_cast<int>( program.size() ); ++i )
    {
        auto args = toArgs( program[static_cast<size_t>( i )] );
        if ( args[0] == "mov" )
        {
            regs[static_cast<std::string>( args[1] )]
                = isRegisterName( args[2] ) ? regs[static_cast<std::string>( args[2] )] : std::stoi( static_cast<std::string>( args[2] ) );
        } else if ( args[0] == "inc" )
        {
            regs[static_cast<std::string>( args[1] )] += 1;
        } else if ( args[0] == "dec" )
        {
            regs[static_cast<std::string>( args[1] )] -= 1;
        } else if ( args[0] == "jnz" )
        {
            if ( ( isRegisterName( args[1] ) && regs[static_cast<std::string>( args[1] )] )
                 || ( !isRegisterName( args[1] ) && std::stoi( static_cast<std::string>( args[1] ) ) ) )
            {
                i += std::stoi( static_cast<std::string>( args[2] ) ) - 1;
            }
        }
    }
    return regs;
}
